using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Runtime.InteropServices;


namespace AjGenesisStudio.Panels
{
    public partial class ExplorerPanel : Fireball.Docking.DockableWindow
    {
        public ExplorerPanel()
        {
            InitializeComponent();
            ShowTree();
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private static ExplorerPanel instance;
        public static ExplorerPanel Instance
        {
            get
            {
                if (instance == null)
                    instance = new ExplorerPanel();
                return instance;
            }
        }

        private string dirpath;
        public string DirectoryPath
        {
            get { return dirpath; }
            set { 
                dirpath = value;
                ShowTree();
            }
        }

        private string selectedPath;
        public string SelectedPath
        {
            get { return selectedPath; }
            set { selectedPath = value; }
        }

        public bool IsLabelEditing
        {
            get {
                bool res = false;
                if (tree.SelectedNodes.Count > 0)
                {
                    TreeNode node = tree.SelectedNodes[0];
                    if (node != null)
                        res = node.IsEditing;
                }
                return res;
            }
        }
	
        private void ShowTree()
        {
            TreeNode node;
            tree.Nodes.Clear();
            if (!string.IsNullOrEmpty(dirpath))
            {
                node = new TreeNode();
                node.Text = Path.GetFileName(dirpath);
                node.ImageIndex = 0;
                node.SelectedImageIndex = 0;
                tree.Nodes.Add(node);
                ShowDirectory(node);
                node.Expand();
            }
        }

        private void ShowDirectory(TreeNode dir_node)
        {
            ShowDirectory(dir_node, false);
        }

        private void ShowDirectory(TreeNode dir_node, bool clear) 
        {
            string path;
            TreeNode node;

            if (clear)
                dir_node.Nodes.Clear();

            if (dir_node.Nodes.Count == 0)
            {
                path = GetNodePath(dir_node);
                foreach (string dir in Directory.GetDirectories(path))
                {
                    node = new TreeNode();
                    node.Text = Path.GetFileName(dir);
                    node.ImageIndex = 1;
                    node.SelectedImageIndex = 1;
                    dir_node.Nodes.Add(node);
                }
                foreach (string file in Directory.GetFiles(path))
                {
                    node = new TreeNode();
                    node.Text = Path.GetFileName(file);
                    node.ImageIndex = Utils.IconExtraction.GetIcon(images, Path.GetExtension(file));
                    node.SelectedImageIndex = node.ImageIndex;
                    dir_node.Nodes.Add(node);
                }
            }
        }

        private string GetNodePath(TreeNode node)
        {
            return Path.Combine(Path.GetDirectoryName(dirpath), node.FullPath);
        }

        private void tree_BeforeSelect(object sender, TreeViewCancelEventArgs e)
        {
            if (Directory.Exists(GetNodePath(e.Node)))
            {
                if (e.Node.Nodes.Count == 0)
                {
                    ShowDirectory(e.Node);
                    e.Node.Expand();
                }
            }
        }

        private void tree_AfterSelect(object sender, TreeViewEventArgs e)
        {
            selectedPath = GetNodePath(e.Node);
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            ShowTree();
        }

        private void tree_NodeMouseDoubleClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            Commands.OpenCommand cmd;
            if (e.Node.Nodes.Count == 0)
            {
                string path = GetNodePath(e.Node);
                cmd = new Commands.OpenCommand();
                cmd.Execute(path);
            }
        }

        private void tree_BeforeCollapse(object sender, TreeViewCancelEventArgs e)
        {
            if (e.Node.Parent != null)
            {
                e.Node.ImageIndex = 1;
                e.Node.SelectedImageIndex = 1;
            }
            else
                e.Cancel = true;
        }

        private void tree_BeforeExpand(object sender, TreeViewCancelEventArgs e)
        {
            if (e.Node.Parent != null)
            {
                e.Node.ImageIndex = 2;
                e.Node.SelectedImageIndex = 2;
            }
        }

        public string[] GetSelectedPaths()
        {
            string[] paths;
            
            paths = new string[tree.SelectedNodes.Count];
            for (int i = 0; i < tree.SelectedNodes.Count; i++)
                paths[i] = GetNodePath(tree.SelectedNodes[i]);
            
            return paths;
        }

        private void tree_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                Point p = new Point(e.X, e.Y);
                if (tree.SelectedNodes.Count > 0)
                {
                    if (tree.SelectedNodes.Count == 1)
                    {
                        if (tree.SelectedNodes[0].ImageIndex <= 2) //es carpeta
                            mnuFolder.Show(tree, p);
                        else
                            mnuFile.Show(tree, p);
                    }
                    else
                    {
                        mnuFile.Show(tree, p);
                        mnuFileRename.Enabled = false;
                        foreach (TreeNode n in tree.SelectedNodes)
                        {
                            if (n.ImageIndex <= 2)
                            {
                                mnuFileOpen.Enabled = false;
                                break;
                            }
                        }
                    }
                }
            }
        }

        private void tree_AfterLabelEdit(object sender, NodeLabelEditEventArgs e)
        {
            if (e.Label != null)
                e.CancelEdit = !Utils.ShellHelper.Rename(GetNodePath(e.Node), e.Label);
        }

        private void EditNode()
        {
            if (tree.SelectedNodes.Count == 1)
                tree.SelectedNodes[0].BeginEdit();
        }

        #region context menu events
        private void mnuFileCut_Click(object sender, EventArgs e)
        {
            (new Commands.EditCommand(Commands.EDITCMDTYPE.Cut)).Execute();
        }

        private void mnuFileCopy_Click(object sender, EventArgs e)
        {
            (new Commands.EditCommand(Commands.EDITCMDTYPE.Copy)).Execute();
        }

        private void mnuFileDelete_Click(object sender, EventArgs e)
        {
            Commands.EditCommand cmd = new Commands.EditCommand(Commands.EDITCMDTYPE.Delete);
            if (cmd.Execute())
            {
                foreach (TreeNode n in tree.SelectedNodes)
                    n.Remove();
            }
        }

        private void mnuFileRename_Click(object sender, EventArgs e)
        {
            EditNode();
        }

        private void mnuFolderCut_Click(object sender, EventArgs e)
        {
            (new Commands.EditCommand(Commands.EDITCMDTYPE.Cut)).Execute();
        }

        private void mnuFolderCopy_Click(object sender, EventArgs e)
        {
            (new Commands.EditCommand(Commands.EDITCMDTYPE.Copy)).Execute();
        }

        private void mnuFolderPaste_Click(object sender, EventArgs e)
        {
            Commands.EditCommand cmd = new Commands.EditCommand(Commands.EDITCMDTYPE.Paste);
            if (cmd.Execute())
                RefreshSelectedFolder();
        }

        private void mnuFolderDelete_Click(object sender, EventArgs e)
        {
            Commands.EditCommand cmd = new Commands.EditCommand(Commands.EDITCMDTYPE.Delete);
            if (cmd.Execute())
            {
                foreach (TreeNode n in tree.SelectedNodes)
                    n.Remove();
            }
        }

        private void mnuFolderRename_Click(object sender, EventArgs e)
        {
            EditNode();
        }

        private void mnuFolderAddNewItem_Click(object sender, EventArgs e)
        {
            (new Commands.NewFileCommand()).Execute();
        }

        private void mnuFolderAddExistingItem_Click(object sender, EventArgs e)
        {
            (new Commands.AddExistingCommand()).Execute();
        }

        private void mnuFolderAddNewFolder_Click(object sender, EventArgs e)
        {
            if (tree.SelectedNodes.Count > 0)
            {
                string folder = GetNodePath(tree.SelectedNodes[0]);
                string newFolder = folder + "\\new folder";
                int n = 1;
                while (Directory.Exists(newFolder))
                {
                    n++;
                    newFolder = folder + "\\new folder (" + n.ToString() + ")";
                }
                Directory.CreateDirectory(newFolder);
                RefreshSelectedFolder();
            }
        }
        #endregion

        private void RefreshSelectedFolder()
        {
            if (tree.SelectedNodes.Count > 0)
            {
                string path = GetNodePath(tree.SelectedNodes[0]);

                if (Directory.Exists(path))
                    ShowDirectory(tree.SelectedNodes[0], true);
            }
        }
    }
}